const std = @import("std");
const httpz = @import("httpz");
const article_server = @import("../server/article_server.zig");
const myjwt = @import("../utils/jwt.zig");
const const_val = @import("../utils/const_value.zig");
const article_model = @import("../model/article.zig");

/// 获取首页文章列表
pub fn getHomeArticles(req: *httpz.Request, res: *httpz.Response) !void {
    _ = req;
    const articles = try article_server.getHomeArticles();
    res.status = 200;
    try res.json(.{ .code = 200, .msg = "ok", .data = articles }, .{});
}

/// 获取文章详情
pub fn getArticleDetail(req: *httpz.Request, res: *httpz.Response) !void {
    const article_id = req.param("id") orelse "";
    if (article_id.len == 0) {
        res.status = 400;
        try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
        return;
    }

    const id = try std.fmt.parseInt(u32, article_id, 10);
    const article_op = try article_server.getArticleDetail(id);
    if (article_op) |article| {
        res.status = 200;
        try res.json(.{ .code = 200, .msg = "ok", .data = article }, .{});
    } else {
        res.status = 404;
        try res.json(.{ .code = 404, .msg = "文章不存在" }, .{});
        return;
    }
}

/// 获取分类下的文章列表
pub fn getArticlesByCateName(req: *httpz.Request, res: *httpz.Response) !void {
    const query = try req.query();
    if (query.get("cate")) |cate_name| {
        const articles = try article_server.getArticlesByCateName(cate_name);
        res.status = 200;
        try res.json(.{ .code = 200, .msg = "ok", .data = articles }, .{});
    } else {
        res.status = 400;
        try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
        return;
    }
}

/// 文章搜索
pub fn searchArticles(req: *httpz.Request, res: *httpz.Response) !void {
    const query = try req.query();
    if (query.get("keyword")) |keyword| {
        // 查询文章总数
        const total = try article_server.getArticleTotalCount();
        // 查询文章列表
        const articles = try article_server.searchArticles(keyword);
        res.status = 200;
        try res.json(.{ .code = 200, .msg = "ok", .total = total, .data = articles }, .{});
    } else {
        res.status = 400;
        try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
        return;
    }
}

/// 获取归档文章
pub fn getArchiveArticles(req: *httpz.Request, res: *httpz.Response) !void {
    _ = req;
    const archives = try article_server.getArchiveArticles();
    res.status = 200;
    try res.json(.{ .code = 200, .msg = "ok", .data = archives }, .{});

    // 返回json时出错，弃用，放到前端处理
    // const DataItem = struct {
    //     year: u32,
    //     articles: []ArchiveArticle,
    // };
    // var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    // const allocator = gpa.allocator();

    // var years_map = std.AutoHashMap(u32, void).init(allocator);
    // defer years_map.deinit();
    // for (archives) |archive| {
    //     const created_year = try std.fmt.parseInt(u32, archive.created_at[0..4], 10);
    //     if (!years_map.contains(created_year)) {
    //         try years_map.put(created_year, {});
    //     }
    // }

    // var datas = std.ArrayList(DataItem).init(allocator);
    // defer datas.deinit();

    // var years_itr = years_map.keyIterator();
    // while (years_itr.next()) |key| {
    //     const year = key.*;

    //     var articles = std.ArrayList(ArchiveArticle).init(allocator);
    //     defer articles.deinit();

    //     for (archives) |archive| {
    //         const created_year = try std.fmt.parseInt(u32, archive.created_at[0..4], 10);
    //         if (created_year == year) {
    //             try articles.append(archive);
    //         }
    //     }

    //     try datas.append(DataItem{
    //         .year = year,
    //         .articles = articles.items,
    //     });
    // }

    // res.status = 200;
    // try res.json(.{ .code = 200, .msg = "ok", .data = datas.items }, .{});
}

/// 分页获取文章列表
pub fn getArticleListPaginate(req: *httpz.Request, res: *httpz.Response) !void {
    const token = req.header("authorization") orelse "";
    // std.debug.print("token: {s}\n", .{token});
    if (token.len == 0) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "未登录" }, .{});
    }

    const exp = myjwt.ExpectedPayload{ .iss = const_val.JWT_ISS, .sub = const_val.JWT_SUB };
    const is_ok = myjwt.verifyToken(exp, token) catch false;
    // std.debug.print("token is ok? {}\n", .{is_ok});
    if (!is_ok) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "token验证失败" }, .{});
    }

    const query = try req.query();
    const page_size_str = query.get("pageSize") orelse "20";
    const page_num_str = query.get("pageNum") orelse "1";
    const page_size = try std.fmt.parseInt(u32, page_size_str, 10);
    const page_num = try std.fmt.parseInt(u32, page_num_str, 10);
    // std.debug.print("page_size: {d}, page_num: {d}\n", .{ page_size, page_num });

    // 查询文章总数
    const total = try article_server.getArticleTotalCount();
    // 查询文章列表
    const articles = try article_server.getArticleListPaginate(page_size, page_num);

    res.status = 200;
    try res.json(.{ .code = 200, .msg = "ok", .total = total, .data = articles }, .{});
}

/// 添加文章
pub fn addArticle(req: *httpz.Request, res: *httpz.Response) !void {
    const token = req.header("authorization") orelse "";
    if (token.len == 0) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "未登录" }, .{});
    }

    const exp = myjwt.ExpectedPayload{ .iss = const_val.JWT_ISS, .sub = const_val.JWT_SUB };
    const is_ok = myjwt.verifyToken(exp, token) catch false;
    if (!is_ok) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "token验证失败" }, .{});
    }

    const post_data = try req.json(article_model.ArticleDtoForCreate);
    if (post_data) |art| {
        const is_add = try article_server.addArticle(art);
        if (!is_add) {
            res.status = 500;
            return try res.json(.{ .code = 500, .msg = "添加文章失败" }, .{});
        }

        res.status = 201;
        try res.json(.{ .code = 200, .msg = "ok", .data = null }, .{});
    } else {
        res.status = 400;
        return try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
    }
}

/// 编辑文章
pub fn editArticle(req: *httpz.Request, res: *httpz.Response) !void {
    const token = req.header("authorization") orelse "";
    if (token.len == 0) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "未登录" }, .{});
    }

    const exp = myjwt.ExpectedPayload{ .iss = const_val.JWT_ISS, .sub = const_val.JWT_SUB };
    const is_ok = myjwt.verifyToken(exp, token) catch false;
    if (!is_ok) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "token验证失败" }, .{});
    }

    const put_data = try req.json(article_model.ArticleDtoForEdit);
    if (put_data) |art| {
        const is_up = try article_server.updateArticle(art);
        if (!is_up) {
            res.status = 500;
            return try res.json(.{ .code = 500, .msg = "文章编辑失败" }, .{});
        }

        res.status = 200;
        try res.json(.{ .code = 200, .msg = "ok", .data = null }, .{});
    } else {
        res.status = 400;
        return try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
    }
}

/// 删除文章
pub fn deleteArticleById(req: *httpz.Request, res: *httpz.Response) !void {
    const id_str = req.param("id") orelse "";
    if (id_str.len == 0) {
        res.status = 400;
        try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
        return;
    }

    const token = req.header("authorization") orelse "";
    if (token.len == 0) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "未登录" }, .{});
    }

    const exp = myjwt.ExpectedPayload{ .iss = const_val.JWT_ISS, .sub = const_val.JWT_SUB };
    const is_ok = myjwt.verifyToken(exp, token) catch false;
    if (!is_ok) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "token验证失败" }, .{});
    }

    const id = std.fmt.parseInt(u32, id_str, 10) catch 0;
    const is_del = try article_server.deleteArticleById(id);
    if (!is_del) {
        res.status = 500;
        return try res.json(.{ .code = 500, .msg = "删除文章失败" }, .{});
    }

    res.status = 200;
    try res.json(.{ .code = 200, .msg = "ok", .data = null }, .{});
}

/// 批量删除文章
pub fn deleteArticleBatch(req: *httpz.Request, res: *httpz.Response) !void {
    const token = req.header("authorization") orelse "";
    if (token.len == 0) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "未登录" }, .{});
    }

    const exp = myjwt.ExpectedPayload{ .iss = const_val.JWT_ISS, .sub = const_val.JWT_SUB };
    const is_ok = myjwt.verifyToken(exp, token) catch false;
    if (!is_ok) {
        res.status = 401;
        return try res.json(.{ .code = 401, .msg = "token验证失败" }, .{});
    }

    const PostData = struct {
        ids: []u32,
    };

    const post_data = req.json(PostData) catch {
        res.status = 400;
        return try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
    };

    if (post_data) |post_ids| {
        const is_del = try article_server.deleteArticleBatch(post_ids.ids);
        if (!is_del) {
            res.status = 500;
            return try res.json(.{ .code = 500, .msg = "批量删除文章失败" }, .{});
        }

        res.status = 200;
        try res.json(.{ .code = 200, .msg = "ok", .data = null }, .{});
    } else {
        res.status = 400;
        return try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
    }
}
